﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors;
using DevExpress.XtraNavBar;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraEditors.Repository;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.LookAndFeel;
using DevExpress.Skins;
using DevExpress.Utils;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraBars;
using Sunboxsoft.WinForm.Shell.Utils;

namespace Sunboxsoft.WinForm.Shell
{
    public class NavigatorManager : INavigatorManager
    {
        private RibbonControl _ribbonControl;
        private SplitContainerControl _ctlSplitContainerControl;
        private NavBarControl _ctlNavBarControl;
        private ApplicationMenu _applicationMenu;
        private RibbonStatusBar _ribbonStatusBar;

        public NavigatorManager(RibbonControl ribbonControl, ApplicationMenu applicationMenu, RibbonStatusBar ribbonStatusBar, SplitContainerControl ctlSplitContainerControl, NavBarControl ctlNavBarControl)
        {
            _ribbonControl = ribbonControl;
            _ctlSplitContainerControl = ctlSplitContainerControl;
            _ctlNavBarControl = ctlNavBarControl;
            _applicationMenu = applicationMenu;
            _ribbonStatusBar = ribbonStatusBar;
        }

        #region INavigatorManager 成员

        public void ShowStatusActions(List<ActionNode> leftActions, List<ActionNode> rightActions)
        {
            for (int index = 0; index < leftActions.Count; index++)
            {
                ActionNode node = leftActions[index];
                DevExpress.XtraEditors.Repository.RepositoryItemTextEdit repositoryItemTextEdit = new DevExpress.XtraEditors.Repository.RepositoryItemTextEdit();
                repositoryItemTextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Simple;
                repositoryItemTextEdit.AllowFocused = false;
                repositoryItemTextEdit.AutoHeight = true;
                repositoryItemTextEdit.ReadOnly = true;
                BarEditItem item = new BarEditItem();
                item.ShowingEditor += new ItemCancelEventHandler(item_ShowingEditor);
                item.Caption = node.Caption;
                item.Width = (node as TextEditActionNode).Width;
                item.Edit = repositoryItemTextEdit;
                item.EditValue = (node as TextEditActionNode).Value;
                _ribbonControl.Items.Add(item);
                _ribbonStatusBar.ItemLinks.Add(item);
            }

            for (int index = 0; index < rightActions.Count; index++)
            {
                ActionNode node = rightActions[index];
                if (node is TextEditActionNode)
                {
                    DevExpress.XtraEditors.Repository.RepositoryItemTextEdit repositoryItemTextEdit = new DevExpress.XtraEditors.Repository.RepositoryItemTextEdit();
                    repositoryItemTextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Simple;
                    repositoryItemTextEdit.AllowFocused = false;
                    repositoryItemTextEdit.AutoHeight = true;
                    repositoryItemTextEdit.ReadOnly = true;
                    BarEditItem item = new BarEditItem();
                    item.ShowingEditor += new ItemCancelEventHandler(item_ShowingEditor);
                    item.Caption = node.Caption;
                    item.Width = (node as TextEditActionNode).Width;
                    item.Edit = repositoryItemTextEdit;
                    item.EditValue = (node as TextEditActionNode).Value;
                    item.Alignment = BarItemLinkAlignment.Right;
                    _ribbonControl.Items.Add(item);
                    _ribbonStatusBar.ItemLinks.Add(item);
                }
            }
        }

        void item_ShowingEditor(object sender, ItemCancelEventArgs e)
        {
            e.Cancel = true;
        }

        public void ShowMenuActions(List<ActionNode> rootMenus)
        {
            ApplicationMenuUtil.ApplyToApplicationMenu(_applicationMenu, rootMenus);
            RibbonPageHeaderUtil.ApplyToRibbonToolbar(_ribbonControl, rootMenus);
        }

        public void ShowPrimaryActions(List<ActionNode> rootNodes)
        {
            Utils.RibbonUtil.ApplyToRibbon(_ribbonControl, rootNodes);
        }

        public void ShowSecondaryActions(ActionNode node)
        {
            ImageCollection images = new ImageCollection(true);
            images.ImageSize = new System.Drawing.Size(16, 16);
            ImageCollection largeImages = new ImageCollection(true);
            largeImages.ImageSize = new System.Drawing.Size(32, 32);

            _ctlNavBarControl.Items.Clear();
            _ctlNavBarControl.Groups.Clear();
            _ctlNavBarControl.AllowSelectedLink = true;
            _ctlNavBarControl.SmallImages = images;
            _ctlNavBarControl.LargeImages = largeImages;

            if (node.Children == null || node.Children.Count == 0)
            {
                _ctlSplitContainerControl.PanelVisibility = SplitPanelVisibility.Panel2;
                return;
            }
            else
            {
                _ctlSplitContainerControl.PanelVisibility = SplitPanelVisibility.Both;
            }

            NavBarGroup defaultGroup = new NavBarGroup();
            //defaultGroup.GroupStyle = NavBarGroupStyle.SmallIconsText;
            defaultGroup.Caption = node.Caption;
            _ctlNavBarControl.Groups.Add(defaultGroup);
            _ctlNavBarControl.ActiveGroup = defaultGroup;
            defaultGroup.Expanded = true;
            if (node.Image != null)
            {
                images.AddImage(node.Image);
                defaultGroup.SmallImageIndex = images.Images.Count - 1;
            }
            //if (node.LargeImage != null)
            //{
            //    largeImages.AddImage(node.LargeImage);
            //    defaultGroup.LargeImageIndex = largeImages.Images.Count - 1;
            //}

            for (int index = 0; index < node.Children.Count; index++)
            {
                ActionNode subAction = node.Children[index];

                if (subAction.Children != null && subAction.Children.Count > 0)
                {
                    ActionNode subAction2 = subAction.Children[index];
                    NavBarGroup group = new NavBarGroup();
                    //defaultGroup.GroupStyle = NavBarGroupStyle.SmallIconsText;
                    group.Caption = subAction2.Caption;
                    _ctlNavBarControl.Groups.Add(defaultGroup);
                    if (subAction2.Image != null)
                    {
                        images.AddImage(subAction2.Image);
                        group.SmallImageIndex = images.Images.Count - 1;
                    }


                    for (int index3 = 0; index3 < subAction2.Children.Count; index3++)
                    {
                        ActionNode subAction3 = subAction2.Children[index];

                        NavBarItem item3 = new NavBarItem(subAction3.Caption);
                        item3.Tag = subAction3;
                        if (subAction3.Image != null)
                        {
                            images.AddImage(subAction3.Image);
                            item3.SmallImageIndex = images.Images.Count - 1;
                        }
                        //if (subAction.LargeImage != null)
                        //{
                        //    largeImages.AddImage(subAction.LargeImage);
                        //    item.LargeImageIndex = largeImages.Images.Count - 1;
                        //}

                        NavBarItemLink link3 = defaultGroup.ItemLinks.Add(item3);

                        item3.LinkClicked += new NavBarLinkEventHandler(item_LinkClicked);
                    }
                }
                else
                {
                    NavBarItem item = new NavBarItem(subAction.Caption);
                    item.Tag = subAction;
                    if (subAction.Image != null)
                    {
                        images.AddImage(subAction.Image);
                        item.SmallImageIndex = images.Images.Count - 1;
                    }
                    //if (subAction.LargeImage != null)
                    //{
                    //    largeImages.AddImage(subAction.LargeImage);
                    //    item.LargeImageIndex = largeImages.Images.Count - 1;
                    //}

                    NavBarItemLink link = defaultGroup.ItemLinks.Add(item);

                    item.LinkClicked += new NavBarLinkEventHandler(item_LinkClicked);

                }
            }
            _ctlNavBarControl.SelectedLink = null;
        }

        public void ActiveAction(ActionNode node)
        {
            for (int index = 0; index < node.UIObjects.Count; index++)
            {
                object uiObject = node.UIObjects[index];
                if (uiObject is BarButtonItem)
                {
                    BarButtonItem button = uiObject as BarButtonItem;
                    if (button.Down == false)
                    {
                        button.PerformClick();
                    }
                }
            }
        }

        void item_LinkClicked(object sender, NavBarLinkEventArgs e)
        {
            NavBarItem item = e.Link.Item;
            ActionNode node = item.Tag as ActionNode;
            if (node.ClickCallback != null)
            {
                node.ClickCallback(sender, e);
            }
        }


        //public void ShowSecondaryActions(ActionNode node)
        //{
        //    _ctlNavBarControl.Items.Clear();
        //    _ctlNavBarControl.Groups.Clear();

        //    if (node.Children == null || node.Children.Count == 0)
        //    {
        //        _ctlSplitContainerControl.PanelVisibility = SplitPanelVisibility.Panel2;
        //        return;
        //    }
        //    else
        //    {
        //        _ctlSplitContainerControl.PanelVisibility = SplitPanelVisibility.Both;
        //    }

        //    NavBarGroup defaultGroup = new NavBarGroup();
        //    defaultGroup.Caption = node.Caption;
        //    defaultGroup.GroupStyle = NavBarGroupStyle.ControlContainer;
        //    _ctlNavBarControl.Groups.Add(defaultGroup);

        //    NavBarGroupControlContainer defaultContainer = new NavBarGroupControlContainer();

        //    TreeList defaultTreeList = new TreeList();

        //    TreeListColumn colName = new TreeListColumn();
        //    RepositoryItemButtonEdit repositoryItemButtonEdit1 = new RepositoryItemButtonEdit();
        //    // 
        //    // colName
        //    // 
        //    colName.Caption = "Name";
        //    colName.ColumnEdit = repositoryItemButtonEdit1;
        //    colName.FieldName = "Caption";
        //    colName.MinWidth = 33;
        //    colName.Name = "colName";
        //    colName.OptionsColumn.AllowFocus = false;
        //    colName.Visible = true;
        //    colName.VisibleIndex = 0;
        //    // 
        //    // repositoryItemButtonEdit1
        //    // 
        //    repositoryItemButtonEdit1.AllowHtmlDraw = DevExpress.Utils.DefaultBoolean.True;
        //    repositoryItemButtonEdit1.AutoHeight = false;
        //    repositoryItemButtonEdit1.Name = "repositoryItemButtonEdit1";
        //    repositoryItemButtonEdit1.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;

        //    defaultTreeList.Columns.AddRange(new TreeListColumn[]{
        //        colName
        //    });

        //    defaultTreeList.CustomDrawNodeCell += new CustomDrawNodeCellEventHandler(defaultTreeList_CustomDrawNodeCell);

        //    defaultTreeList.Dock = System.Windows.Forms.DockStyle.Fill;
        //    defaultTreeList.Location = new System.Drawing.Point(0, 0);
        //    defaultTreeList.Name = "treeList1";
        //    defaultTreeList.OptionsBehavior.Editable = false;
        //    defaultTreeList.OptionsView.ShowColumns = false;
        //    defaultTreeList.OptionsView.ShowHorzLines = false;
        //    defaultTreeList.OptionsView.ShowIndentAsRowStyle = true;
        //    defaultTreeList.OptionsView.ShowIndicator = false;
        //    defaultTreeList.OptionsView.ShowVertLines = false;
        //    defaultTreeList.RepositoryItems.AddRange(new DevExpress.XtraEditors.Repository.RepositoryItem[] { repositoryItemButtonEdit1 });
        //    //defaultTreeList.SelectImageList = this.icFolders;
        //    defaultTreeList.Size = new System.Drawing.Size(224, 416);
        //    defaultTreeList.TabIndex = 0;

        //    defaultContainer.Controls.Add(defaultTreeList);
        //    defaultGroup.ControlContainer = defaultContainer;


        //    for (int index = 0; index < node.Children.Count; index++)
        //    {
        //        ActionNode subAction = node.Children[index];
        //        TreeListNode tlNode = defaultTreeList.AppendNode(new object[] { subAction.Caption, subAction }, null);
        //        //if (subAction.Children != null && subAction.Children.Count > 0)
        //        //{
        //        //}
        //        //else
        //        //{
        //        //}
        //    }
        //    defaultTreeList.ExpandAll();
        //}

        void defaultTreeList_CustomDrawNodeCell(object sender, CustomDrawNodeCellEventArgs e)
        {
            TreeList treeList = sender as TreeList;
            //bool ShowAllMessageCount = true;
            if (e.Column.Name == "colName")
            {
                string textColor = GetHtmlTextColor(treeList.FocusedNode.Equals(e.Node));
                object textValue = e.Node.GetValue(treeList.Columns[0]);
                e.CellText = string.Format("<Color={1}>{0}", textValue, textColor);
                //if (e.Node.ParentNode == null || !(DataHelper.ShowAllMessageCount || DataHelper.ShowUnreadMessageCount))
                //    return;
                //List<Message> list = e.Node.GetValue(colData) as List<Message>;
                //int unread = 3;
                //if (unread > 0)
                //{
                //    if (ShowAllMessageCount)
                //        e.CellText = string.Format("<Color={5}><b>{0}</b><Size=-1><Color={2}> [{1}/<Color={4}>{3}<Color={2}>]", textValue, unread, ColorHelper.HtmlQuestionColor, list.Count, ColorHelper.HtmlWarningColor, textColor);
                //    else
                //        e.CellText = string.Format("<Color={3}><b>{0}</b><Size=-1><Color={2}> [{1}]", textValue, unread, ColorHelper.HtmlQuestionColor, textColor);
                //}
                //else
                //{
                //    if (ShowAllMessageCount && list.Count > 0)
                //        e.CellText = string.Format("<Color={3}>{0}<Size=-1><Color={2}> [{1}]", textValue, list.Count, ColorHelper.HtmlWarningColor, textColor);
                //}
            }
        }

        static string GetHtmlTextColor(bool focused)
        {
            if (focused)
                return ColorHelper.HtmlHighlightTextColor;
            return ColorHelper.HtmlControlTextColor;
        }
        #endregion
    }

    public class ColorHelper
    {
        public static void UpdateColor(ImageList list, UserLookAndFeel lf)
        {
            for (int i = 0; i < list.Images.Count; i++)
                list.Images[i] = SetColor(list.Images[i] as Bitmap, GetHeaderForeColor(lf));
        }
        public static Color GetHeaderForeColor(UserLookAndFeel lf)
        {
            Color ret = SystemColors.ControlText;
            if (lf.ActiveStyle != ActiveLookAndFeelStyle.Skin) return ret;
            return GridSkins.GetSkin(lf)[GridSkins.SkinHeader].Color.GetForeColor();
        }
        static Bitmap SetColor(Bitmap bmp, Color color)
        {
            for (int i = 0; i < bmp.Width; i++)
                for (int j = 0; j < bmp.Height; j++)
                    if (bmp.GetPixel(i, j).Name != "0")
                        bmp.SetPixel(i, j, color);
            return bmp;
        }
        public static string HtmlHyperLinkTextColor
        {
            get
            {
                Color color = EditorsSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default).Colors.GetColor("HyperLinkTextColor");
                return GetRGBColor(color);
            }
        }
        public static string HtmlHighlightTextColor
        {
            get
            {
                Color color = CommonSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default).Colors.GetColor("HighlightText");
                return GetRGBColor(color);
            }
        }
        public static string HtmlControlTextColor
        {
            get
            {
                Color color = CommonSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default).Colors.GetColor("ControlText");
                return GetRGBColor(color);
            }
        }
        public static string HtmlQuestionColor
        {
            get
            {
                Color color = CommonColors.GetQuestionColor(DevExpress.LookAndFeel.UserLookAndFeel.Default);
                return GetRGBColor(color);
            }
        }
        public static string HtmlWarningColor
        {
            get
            {
                Color color = CommonColors.GetWarningColor(DevExpress.LookAndFeel.UserLookAndFeel.Default);
                return GetRGBColor(color);
            }
        }
        public static Color DisabledTextColor
        {
            get
            {
                return CommonSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default).Colors.GetColor("DisabledText");
            }
        }
        public static Color CriticalColor
        {
            get
            {
                return CommonColors.GetCriticalColor(DevExpress.LookAndFeel.UserLookAndFeel.Default);
            }
        }
        public static Color WarningColor
        {
            get
            {
                return CommonColors.GetWarningColor(DevExpress.LookAndFeel.UserLookAndFeel.Default);
            }
        }
        static string GetRGBColor(Color color)
        {
            return string.Format("{0},{1},{2}", color.R, color.G, color.B);
        }
    }
}
